﻿//  Copyright (c) 2009 Ray Liang (http://www.dotnetage.com)
//  Dual licensed under the MIT and GPL licenses:
//  http://www.opensource.org/licenses/mit-license.php
//  http://www.gnu.org/licenses/gpl.html
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DNA.Mvc.jQuery
{
    /// <summary>
    /// Defines the jQuery UI Draggable plugin options.
    /// </summary>
    public class DraggableOptions
    {
        /// <summary>
        /// Allows the draggable to be dropped onto the specified sortables
        /// </summary>
        /// <remarks>
        /// If this propety is used (helper must be set to 'Clone' in order to work flawlessly), 
        /// a draggable can be dropped onto a sortable list and then becomes part of it. 
        /// </remarks>
        [jQueryOption("connectToSortable")]
        public string ConnectToSortable { get; set; }

        /// <summary>
        ///  Gets/Sets whether prevent the ui-draggable class from being added. 
        ///  </summary>
        /// <remarks>
        /// This may be desired as a performance optimization when using Draggable on many hundreds of elements.
        /// </remarks>
        [jQueryOption("addClasses")]
        public bool? AllowAddClasses { get; set; }

        /// <summary>
        /// Gets/Sets whether prevent iframes from capturing the mousemove events during a drag. 
        /// </summary>
        /// <remarks>
        /// Useful in combination with cursorAt, or in any case, if the mouse cursor is not over the helper.
        /// If set to true, transparent overlays will be placed over all iframes on the page. If a selector is supplied, 
        /// the matched iframes will have an overlay placed over them.
        /// </remarks>
        [jQueryOption("iframeFix")]
        public bool? PreventiFrameCapturing { get; set; }

        /// <summary>
        /// Gets/Sets whether droppable positions are calculated on every mousemove. 
        /// </summary>
        /// <remarks>
        /// Caution: This solves issues on highly dynamic pages, but dramatically decreases performance.
        /// </remarks>
        [jQueryOption("refreshPositions")]
        public bool? RefreshPositions { get; set; }

        /// <summary>
        ///  Gets/Sets whether the element will return to its start position when dragging stops. 
        ///  </summary>
        [jQueryIgnore]
        public RevertModes RevertMode { get; set; }

        /// <summary>
        /// Gets/Sets the duration of the revert animation, in milliseconds. Ignored if Revert is NotSet.
        /// </summary>
        [jQueryOption("revertDuration")]
        public int? RevertDuration { get; set; }

        /// <summary>
        /// Gets/Sets the group sets of draggable and droppable items, in addition to droppable's Accept Property. 
        /// </summary>
        /// <remarks>
        /// A draggable with the same scope value as a droppable will be accepted by the droppable.
        /// </remarks>
        [jQueryOption("scope")]
        public string GroupName { get; set; }

        /// <summary>
        ///  Get/Sets whether draggable can snap to the edges of the selected elements when near an edge of the element.
        /// </summary>
        [jQueryOption("snap")]
        public bool? AllowSnap { get; set; }

        /// <summary>
        /// Get/Sets determines which edges of snap elements the draggable will snap to. Ignored if AllowSnap is false. 
        /// Possible values: 'Inner', 'Outer', 'Both','NotSet'
        /// </summary>
        //[jQueryOption("snapMode")]
        [jQueryIgnore]
        public SnapModes SnapMode { get; set; }

        /// <summary>
        /// Gets/Sets the selector that the draggable will snap to the edges of the selected elements when near 
        /// an edge of the element.
        /// </summary>
        [jQueryIgnore]
        public string SnapTo { get; set; }

        /// <summary>
        /// Gets/Sets the offset in pixels from the snap element edges at which snapping should occur. 
        /// Ignored if AllowSnap is false.
        /// </summary>
        [jQueryOption("snapTolerance")]
        public int? SnapOffset { get; set; }

        [jQueryOption("stack", ValueType = JavaScriptTypes.JSON)]
        public object Stack { get; set; }

        /// <summary>
        /// Gets/Sets prevents dragging from starting on specified Controls/Elements.
        /// </summary>
        [jQueryOption("cancel")]
        public string DisableDraggingElements { get; set; }

        /// <summary>
        /// Gets/Sets the litimation of the draggable element's dragging orientation.
        /// </summary>
        [jQueryIgnore]
        public Orientation DragOrientation { get; set; }

        /// <summary>
        ///  Gets/Sets restricts drag start click to the specified elements
        /// </summary>
        [jQueryOption("handle")]
        public string DragHandler { get; set; }

        /// <summary>
        /// Gets/Sets a helper element to be used for dragging display.
        /// </summary>
        [jQueryIgnore]
        public Helpers DragHelper { get; set; }

        /// <summary>
        /// Gets/Sets the custom helper html
        /// </summary>
        [jQueryIgnore]
        public string CustomHelper { get; set; }

        /// <summary>
        /// Constrains dragging to within the bounds of the specified element.
        /// Possible string values: 'parent', 'document', 'window'
        /// </summary>
        [jQueryOption("appendTo")]
        public string AppendTo { get; set; }

        /// <summary>
        /// Constrains dragging to within the bounds of the specified element or region. Possible string values: 'parent', 'document', 'window', [x1, y1, x2, y2].
        /// </summary>
        [jQueryIgnore]
        public int[] ContainmentBounds { get; set; }
        
        [jQueryIgnore]
        public Containers ContainsIn { get; set; }

        /// <summary>
        /// Gets/Sets the id of  the container.
        /// </summary>
        [jQueryIgnore]
        public string Container { get; set; }

        /// <summary>
        /// Gets/Sets whether container auto-scrolls while dragging.
        /// </summary>
        [jQueryOption("scroll")]
        public bool? AutoScroll { get; set; }

        /// <summary>
        /// Gets/Sets distance in pixels from the edge of the viewport after which the viewport should scroll. 
        /// Distance is relative to pointer, not the draggable.
        /// </summary>
        [jQueryOption("scrollSensitivity")]
        public int? ScrollSensitivity { get; set; }

        /// <summary>
        /// Gets/Sets time in milliseconds after mousedown until dragging should start.
        /// </summary>
        /// <remarks>
        /// This Property can be used to prevent unwanted drags when clicking on an element.
        /// </remarks>
        [jQueryOption("delay")]
        public int? DragStartDelay { get; set; }

        /// <summary>
        /// Gets/Sets DragDistance in pixels after mousedown the mouse must move before dragging should start. 
        /// </summary>
        ///<remarks>
        /// This Property can be used to prevent unwanted drags when clicking on an element.
        /// </remarks>
        [jQueryOption("distance")]
        public int? DragStartDistance { get; set; }

        /// <summary>
        /// The css cursor during the drag operation.
        /// </summary>
        [jQueryOption("cursor")]
        public string Cursor { get; set; }

        /// <summary>
        /// Moves the dragging helper so the cursor always appears to drag from the same position. 
        /// Coordinates can be given as a hash using a combination of one or two keys: { Top, Left, Right, Bottom }.
        /// </summary>
        [jQueryOption("cursorAt", ValueType = JavaScriptTypes.Object)]
        public Position CursorPosition { get; set; }

        [jQueryOption("grid", ValueType = JavaScriptTypes.Array)]
        public int[] Grid { get; set; }

        /// <summary>
        /// Gets/Sets the speed at which the window should scroll once the mouse pointer gets within the 
        /// scrollSensitivity distance.
        /// </summary>
        [jQueryOption("scrollSpeed")]
        public int? ScrollSpeed { get; set; }

        /// <summary>
        /// Gets/Sets opacity for the helper while being dragged.
        /// </summary>
        [jQueryOption("opacity")]
        public float? DragHelperOpacity { get; set; }

        /// <summary>
        /// Gets/Sets z-index for the helper while being dragged.
        /// </summary>
        [jQueryOption("zIndex")]
        public int? ZIndex { get; set; }

        /// <summary>
        /// Gets/Sets  the z-Index of the defined group automatically, 
        /// always brings to front the dragged item. Very useful in things like window managers. 
        /// </summary>
        public int? GroupMinZIndex { get; set; }

        /// <summary>
        /// This event is triggered when dragging starts
        /// </summary>
        [jQueryOption("start", ValueType = JavaScriptTypes.Function, FunctionParams = new string[] { "event", "ui" })]
        public string OnDragStart { get; set; }

        /// <summary>
        /// This event is triggered when the mouse is moved during the dragging
        /// </summary>
        [jQueryOption("drag", ValueType = JavaScriptTypes.Function, FunctionParams = new string[] { "event", "ui" })]
        public string OnDrag { get; set; }

        /// <summary>
        /// This event is triggered when dragging stops
        /// </summary>
        [jQueryOption("stop", ValueType = JavaScriptTypes.Function, FunctionParams = new string[] { "event", "ui" })]
        public string OnDragStop { get; set; }
    }

    /// <summary>
    /// Defines the Position class.
    /// </summary>
    public class Position
    {
        /// <summary>
        /// Gets/Sets the currsor.
        /// </summary>
        [jQueryOption("cursor")]
        public string Cursor { get; set; }
        
        /// <summary>
        /// Gets/Sets the top value.
        /// </summary>
        [jQueryOption("top")]
        public int? Top { get; set; }

        /// <summary>
        /// Gets/Sets the left value
        /// </summary>
        [jQueryOption("left")]
        public int? Left { get; set; }

        /// <summary>
        /// Gets/Sets the bottom value.
        /// </summary>
        [jQueryOption("bottom")]
        public int? Bottom { get; set; }

        /// <summary>
        /// Gets/Sets the right value.
        /// </summary>
        [jQueryOption("right")]
        public int? Right { get; set; }
    }
}
